package com.kgcx.organization.controller;

import com.kgcx.common.annotation.validator.IdValidator;
import com.kgcx.common.bean.RequestData;
import com.kgcx.common.bean.ReturnData;
import com.kgcx.common.constant.Cons;
import com.kgcx.common.controller.BaseController;
import com.kgcx.common.redis.JsonRedisTemplate;
import com.kgcx.common.redis.RedisCons;
import com.kgcx.common.utils.SmsUtils;
import com.kgcx.common.utils.TokenUtils;
import com.kgcx.organization.domain.Driver;
import com.kgcx.organization.domain.DriverMsg;
import com.kgcx.organization.domain.DriverMsgType;
import com.kgcx.organization.service.DriverMsgService;
import com.kgcx.organization.service.DriverService;
import com.kgcx.organization.vo.DriverVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Api(description = "司机接口", tags = "司机接口")
@RestController
@RequestMapping("driver")
public class DriverController extends BaseController {

    @Autowired
    private DriverService driverService;

    @Autowired
    private DriverMsgService driverMsgService;

    @Autowired
    private JsonRedisTemplate jsonRedisTemplate;

    @ApiOperation(value = "查询司机", httpMethod = "GET", notes = "这是用来查询司机的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "kid", value = "用户ID", required = false, access = "group", paramType = "query", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "phone", value = "电话", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "token", value = "令牌", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "licenseId", value = "机动车驾驶证编号", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("getDriver")
    public ReturnData<Driver> getDriver() {

        Driver driver = driverService.getDriver(this.getRequestData());
        return new ReturnData<>(driver);
    }

    @ApiOperation(value = "查询司机(简要信息)", httpMethod = "GET", notes = "这是用来查询司机(简要信息)的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "kid", value = "用户ID", required = false, access = "group", paramType = "query", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "phone", value = "电话", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "token", value = "令牌", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "licenseId", value = "机动车驾驶证编号", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("getDriverMini")
    public ReturnData<DriverVO> getDriverMini() {

        Driver driver = driverService.getDriver(this.getRequestData());
        DriverVO driverVO = new DriverVO();
        if (driver != null) {
            BeanUtils.copyProperties(driver, driverVO);
        }
        return new ReturnData<>(driverVO);
    }

    @ApiOperation(value = "查询司机", httpMethod = "GET", notes = "这是用来查询司机的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页码", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pageSize", value = "页容量", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "orderBy", value = "排序,sql格式", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "name", value = "名字", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "driverId", value = "id", required = false, paramType = "query", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "idCardNumber", value = "身份证号码", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "createTime", value = "录入时间", required = false, paramType = "query", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "autoId", value = "车辆id", required = false, paramType = "query", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "cityId", value = "城市ID", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "isBind", value = "是否已绑定车辆,0=未绑定，1=已绑定", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "companyId", value = "人力服务公司id", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "autoTypeId", value = "用车类型", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "state", value = "司机状态", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "stateIn", value = "司机状态,多选，逗号分隔", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("getDriverList")
    public ReturnData<List<Driver>> getDriverList() {
        RequestData rd = this.getRequestData();
        List<Driver> driverList = driverService.getDriverList(rd);
        return new ReturnData<>(driverList);
    }

    @ApiOperation(value = "登录司机", httpMethod = "POST", notes = "这是用来登录司机的接口")
    @ApiImplicitParams({

            @ApiImplicitParam(name = "phone", value = "电话", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "code", value = "验证码", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "mac", value = "mac", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "imei", value = "imei", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "imsi", value = "imsi", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class)
    })
    @PostMapping("login")
    public ReturnData<String> login() {
        RequestData rd = this.getRequestData();
        if (StringUtils.isNotBlank(rd.getString("code"))) {
            Object code = jsonRedisTemplate.opsForValue().get(Driver.SMS_VALIDATE_LOGIN_KEY_PREFIX + rd.getString("phone"));
            if (!ObjectUtils.allNotNull(code, rd.getString("code")) || ObjectUtils.notEqual(code, rd.getString("code"))) {
                return new ReturnData<>("-1", "验证码错误！");
            }
        }
        Driver driver = driverService.login(rd);
        if (null != driver) {
            String token = TokenUtils.getToken(driver.getKid(), TokenUtils.TOKEN_SUBJECT_DRIVER);
            jsonRedisTemplate.opsForHash().put(RedisCons.TOKEN, TokenUtils.getTokenKey(driver.getKid(), TokenUtils.TOKEN_SUBJECT_DRIVER), token);
            return new ReturnData<>(token);
        }
        return new ReturnData<>("-1", "帐号或密码错误");
    }


    @ApiOperation(value = "新增司机", httpMethod = "POST", notes = "这是用来新增司机的接口")
    @PostMapping("addDriver")
    public ReturnData addDriver(@RequestBody Driver driver) {
        Driver d = driverService.getDriver(null, driver.getPhone());
        if (null != d) {
            return new ReturnData("-1", "手机号已被注册");
        }
        driverService.addDriver(driver);
        return new ReturnData();
    }

    @ApiOperation(value = "修改司机", httpMethod = "POST", notes = "这是用来修改司机的接口")
    @PostMapping("updateDriver")
    public ReturnData updateDriver(@RequestBody Driver driver) {
        driverService.updateDriver(driver);
        return new ReturnData();
    }

    @ApiOperation(value = "删除司机", httpMethod = "POST", notes = "这是用来删除司机的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "kid", value = "用户ID", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class)
    })
    @PostMapping("removeDriver")
    public ReturnData removeDriver(@RequestParam Long kid) {
        driverService.removeDriver(kid);
        return new ReturnData();
    }

    @ApiOperation(value = "变更司机状态", httpMethod = "POST", notes = "状态：0=离线，1=上线，2=待命，3=入栈中，4=入栈，5=服务中")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "kid", value = "用户ID", required = true, paramType = "query", dataType = "String", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "state", value = "状态", required = true, paramType = "query", dataType = "String", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "lat", value = "纬度", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "lng", value = "经度", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "airportId", value = "待命机场ID", required = false, paramType = "query", dataType = "Long", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "stationId", value = "高铁站ID", required = false, paramType = "query", dataType = "Long", dataTypeClass = Long.class),
    })
    @PostMapping("updateDriverState")
    public ReturnData updateDriverState(@RequestParam Long kid, //
                                        @RequestParam Integer state, //
                                        @RequestParam String lat, //
                                        @RequestParam String lng, //
                                        @RequestParam(required = false) Long airportId, //
                                        @RequestParam(required = false) Long stationId //
    ) {
        Driver driver = driverService.getDriver(kid, null);
        if (driver == null) {
            return new ReturnData("16101000001", "司机不存在！");
        }
        // 司机为服务中时，不允许前台修改司机状态
        if (Cons.DRIVER_STATE_RUN.equals(driver.getState())) {
            return new ReturnData("16101000002", "接单中，不能变更状态！");
        }
        if (airportId != null && stationId != null) {
            return new ReturnData("16101000003", "不能同时待命机场和高铁站！");
        }

        driverService.updateDriverState(kid, state, lat, lng, airportId, stationId);
        return new ReturnData();
    }

    @ApiOperation(value = "发送验证码", httpMethod = "GET", notes = "发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "电话", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "type", value = "类型,1=登录，2=重置密码", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("code")
    public ReturnData<String> code(@RequestParam String phone, @RequestParam String type) {
        String code = SmsUtils.sendCode(phone);
        if ("1".equals(type)) {
            jsonRedisTemplate.opsForValue().set(Driver.SMS_VALIDATE_LOGIN_KEY_PREFIX + phone, code, 600, TimeUnit.SECONDS);
        } else {
            jsonRedisTemplate.opsForValue().set(Driver.SMS_VALIDATE_RESETPASSWORD_KEY_PREFIX + phone, code, 600, TimeUnit.SECONDS);
        }

        return new ReturnData<>();
    }

    @ApiOperation(value = "修改密码", httpMethod = "POST", notes = "修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "电话", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "code", value = "密码", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
    })
    @PostMapping("resetPassword")
    public ReturnData resetPassword(@RequestParam String phone,
                                    @RequestParam String password,
                                    @RequestParam String code) {
        Object c = jsonRedisTemplate.opsForValue().get(Driver.SMS_VALIDATE_RESETPASSWORD_KEY_PREFIX + phone);
        if (!ObjectUtils.allNotNull(c, code) || ObjectUtils.notEqual(c, code)) {
            return new ReturnData<>("-1", "验证码错误！");
        }
        Long tokenKid = this.getTokenKid();
        Driver driver = driverService.getDriver(tokenKid, phone);
        if (driver == null) {
            return ReturnData.NO_PERMISSION;
        }
        driverService.resetPassword(phone, password);
        return new ReturnData<>();
    }

    @ApiOperation(value = "获取未读消息数量", httpMethod = "GET", notes = "获取未读消息数量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "driverId", value = "司机id", required = true, paramType = "query", dataType = "long", dataTypeClass = Long.class),
    })
    @GetMapping("getDriverMsgUnreadCount")
    @IdValidator("driverId")
    public ReturnData<Integer> getDriverMsgUnreadCount(@RequestParam Long driverId) {
        return new ReturnData<>(driverMsgService.getDriverMsgUnreadCount(driverId));
    }

    @ApiOperation(value = "消息中心概览", httpMethod = "GET", notes = "消息中心概览")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "driverId", value = "司机id", required = true, paramType = "query", dataType = "long", dataTypeClass = Long.class),
    })
    @GetMapping("getDriverMsgOverview")
    @IdValidator("driverId")
    public ReturnData<List<DriverMsgType>> getDriverMsgOverview(@RequestParam Long driverId) {
        return new ReturnData<>(driverMsgService.getDriverMsgOverview(driverId));
    }

    @ApiOperation(value = "查询消息", httpMethod = "GET", notes = "查询消息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "driverId", value = "司机id", required = true, paramType = "query", dataType = "String", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "typeId", value = "消息类型", required = true, paramType = "query", dataType = "String", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pageNum", value = "页码", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pageSize", value = "页容量", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "orderBy", value = "排序,sql格式", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
    })
    @GetMapping("getDriverMsgList")
    @IdValidator("driverId")
    public ReturnData<List<DriverMsg>> getDriverMsgList() {
        return new ReturnData<>(driverMsgService.getDriverMsgList(this.getRequestData()));
    }


    @ApiOperation(value = "答复入栈邀请", httpMethod = "POST", notes = "parkState：101-待确认、102-入栈中、103-已入栈、104-已开走、105、已取消")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "driverId", value = "司机ID", required = true, paramType = "query", dataType = "Long", dataTypeClass = Long.class), //
            @ApiImplicitParam(name = "parkState", value = "泊车状态", required = true, paramType = "query", dataType = "int", dataTypeClass = Integer.class) //
    })
    @PostMapping("updateParkState")
    public ReturnData updateParkState(@RequestParam Long driverId, //
                                      @RequestParam Integer parkState //
    ) {
        driverService.updateParkState(driverId, parkState);
        return new ReturnData();
    }

    /**
     * 专给监管平台提供查询
     */
    @ApiOperation(value = "监管平台查询司机", httpMethod = "GET", notes = "这是用来给监管平台查询司机的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页码", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pageSize", value = "页容量", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "orderBy", value = "排序,sql格式", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "cityId", value = "城市ID", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "isBind", value = "是否已绑定车辆,0=未绑定，1=已绑定", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "companyId", value = "人力服务公司id", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "autoTypeId", value = "用车类型", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "state", value = "司机状态", required = false, paramType = "query", dataType = "int", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "stateIn", value = "司机状态,多选，逗号分隔", required = false, paramType = "query", dataType = "String", dataTypeClass = String.class)
    })
    @GetMapping("queryDriverWithPage")
    public ReturnData<List<Driver>> queryDriverWithPage() {
        RequestData rd = this.getRequestData();
        List<Driver> driverList = driverService.queryDriverWithPage(rd);
        return new ReturnData<>(driverList);
    }
}
